﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.IO;
using Engine.Sgml.Configuration;
using Engine.Sgml.Validation;
using Engine.Sgml.Allocation;
using Engine.Sgml.Validation.Rules;
using Engine.Dtd.Schema;

namespace Engine.Sgml.Test {
    /// <summary>
    /// Summary description for ConfigurationFixture
    /// </summary>
    [TestClass]
    public class DocumentConfigurationTest {
        public DocumentConfigurationTest() {
            //
            // TODO: Add constructor logic here
            //
            }

        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext {
            get {
                return testContextInstance;
                }
            set {
                testContextInstance = value;
                }
            }

        #region Additional test attributes
        //
        // You can use the following additional attributes as you write your tests:
        //
        // Use ClassInitialize to run code before running the first test in the class
        // [ClassInitialize()]
        // public static void MyClassInitialize(TestContext testContext) { }
        //
        // Use ClassCleanup to run code after all tests in a class have run
        // [ClassCleanup()]
        // public static void MyClassCleanup() { }
        //
        // Use TestInitialize to run code before running each test 
        [TestInitialize()]
        public void MyTestInitialize() {
            DirectoryInfo fileDirectory = Directory.GetParent(TestContext.TestDir).Parent;

            DirectoryInfo schemaDirectory = new DirectoryInfo(Path.Combine(fileDirectory.FullName, @"Engine.Sgml.Test\Scheme Samples"));
            DirectoryInfo saveDirectory = new DirectoryInfo(Path.Combine(fileDirectory.FullName, @"Engine.Sgml.Test\Saved Docs"));
            fileDirectory = new DirectoryInfo(Path.Combine(fileDirectory.FullName, @"Engine.Sgml.Test\Document Samples"));

            Assert.IsTrue(schemaDirectory.Exists);
            Assert.IsTrue(fileDirectory.Exists);
            Assert.IsTrue(saveDirectory.Exists);

            fileDir = fileDirectory.FullName;
            }
        //
        // Use TestCleanup to run code after each test has run
        // [TestCleanup()]
        // public void MyTestCleanup() { }
        //
        #endregion

        private string fileDir;

        [TestMethod]
        public void PreserveWhiteSpaceTest() {
            SgmlDocument doc = new SgmlDocument();
            doc.ValidatorBehavior.PreserveWhitespace = true;
            doc.Load(new Uri(Path.Combine(fileDir, "Preserve WhiteSpace.HTML")));

            string html = doc.ToString(true);
            }

        [TestMethod]
        public void SgmlBehaviorChangedTest() {
            SgmlDocument doc = new SgmlDocument();
            // Default value is FALSE
            doc.ValidatorBehavior.PreserveWhitespace = true;

            doc.ValidatorBehavior.PreserveWhitespace = false;
            doc.ValidatorBehavior.DtdDisabled = true;
            doc.ValidatorBehavior.DtdDisabled = false;

            doc.ValidatorBehavior.PreserveWhitespace = true;
            doc.ValidatorBehavior.DtdDisabled = true;
            doc.ValidatorBehavior.DtdDisabled = false;

            doc.ValidatorBehavior.PreserveWhitespace = false;
            doc.ValidatorBehavior.PreserveWhitespace = true;
            }

        [TestMethod]
        public void CaseSensitiveTagsIsFalse() {
            SgmlDocument doc = new SgmlDocument();

            doc.ValidatorBehavior.CaseSensitiveTags = false;
            doc.Load(new Uri(Path.Combine(fileDir, "Document Configuration 001.xml")));

            string content = doc.ToString();
            string xml = doc.ToXml();

            Assert.IsNotNull(doc.SelectElement(".//BODY/DIV[1]"));
            Assert.IsNotNull(doc.SelectElement(".//BODY/div[1]"));
            Assert.IsNotNull(doc.SelectElement(".//BODY/div[2]"));
            }

        [TestMethod]
        public void CaseSensitiveTagsIsTure() {
            SgmlDocument doc = new SgmlDocument();

            doc.ValidatorBehavior.CaseSensitiveTags = true;
            doc.Load(new Uri(Path.Combine(fileDir, "Document Configuration 001.xml")));

            string content = doc.ToString();
            string xml = doc.ToXml();

            Assert.IsNotNull(doc.SelectElement(".//BODY/DIV[1]/div"));
            Assert.IsNotNull(doc.SelectElement(".//BODY/div[1]"));
            }

        [TestMethod]
        public void RemoveIllegalElementsIsTrue() {
            SgmlDocument doc = new SgmlDocument();

            doc.ValidatorBehavior.CaseSensitiveTags = true;
            doc.ValidatorBehavior.RemoveIllegalElements = true;
            doc.Load(new Uri(Path.Combine(fileDir, "Document Configuration 003.xml")));

            string content = doc.ToString();
            string xml = doc.ToXml();

            Assert.IsTrue(doc.SelectElement(".//BODY").Elements().Count() == 2);
            Assert.IsNotNull(doc.SelectElement(".//BODY/DIV"));
            Assert.IsNotNull(doc.SelectElement(".//BODY/text()"));
            }

        [TestMethod]
        public void IgnoreComments() {
            SgmlDocument doc = new SgmlDocument();

            doc.ValidatorBehavior.IgnoreComments = true;
            doc.ValidatorBehavior.CaseSensitiveTags = false;
            doc.Load(new Uri(Path.Combine(fileDir, "Document Configuration 002.xml")));

            string content = doc.ToString();
            string xml = doc.ToXml();

            SElement element = doc.SelectElement(".//HEAD/*");
            Assert.IsTrue(element.NodeType != SgmlNodeType.Comment);
            element = doc.SelectElement(".//BODY/*");
            Assert.IsNull(element);
            element = doc.Root.FirstNode.LastNode;
            Assert.IsTrue(element.NodeType != SgmlNodeType.Comment);
            }

        [TestMethod]
        public void ProhibitDtdSchema() {
            SgmlDocument doc = new SgmlDocument();

            doc.ValidatorBehavior.DtdDisabled = true;

            doc.Load(new Uri(Path.Combine(fileDir, "Document Configuration 004.xml")));

            string content = doc.ToString();
            string xml = doc.ToXml();

            Assert.IsTrue(doc.Root.Elements().Count() == 1);
            Assert.IsNotNull(doc.SelectElement("Deployment"));
            Assert.IsNotNull(doc.SelectElement("Deployment/img/table"));
            Assert.IsNotNull(doc.SelectElement("Deployment/table/tr"));
            Assert.IsNotNull(doc.SelectElement("Deployment/table/li"));
            Assert.IsNotNull(doc.SelectElement("Deployment/tr"));
            }

        //[TestMethod]
        //public void AddCustomValidationRules() {
        //    DtdSchema schema = DtdSchema.Load();
        //    SgmlDocument doc = new SgmlDocument(schema);

        //    SgmlValidatorSettings validatorSettings = doc.Settings.ValidatorSettings;
        //    validatorSettings.Rules.Add(new Engien.Sgml.Test.Fistures.CustomRule(schema));

        //    doc.Load(new Uri(Path.Combine(fileDir, "Document Configuration 005.xml")));

        //    string content = doc.ToString();
        //    string xml = doc.ToXml();

        //    Assert.IsNotNull(doc.SelectElement(".//table/TBODY/TR[1]/th"));
        //    Assert.IsNotNull(doc.SelectElement(".//table/TBODY/TR/th[position() = last()]"));
        //    }
        }
    }
